package com.ruoyi.web.utils;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.aliyun.dysmsapi20170525.models.SendSmsResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.RnxSmsSendLog;
import com.ruoyi.system.service.IRnxSmsSendLogService;
import com.ruoyi.web.core.config.AdminConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.CompletableFuture;

/**
 * @author yangtaoer
 * 短信下发服务
 */
@Slf4j
@Service
public class SmsSender {

	static IRnxSmsSendLogService sendLogService;

	private static final String SMS_SEND_STATE_OK = "OK";

	/**
	 * 短信日志存储
	 */
	@Autowired
	private IRnxSmsSendLogService rnxSmsSendLogService;

	@PostConstruct
	public void init() {
		sendLogService = rnxSmsSendLogService;
	}

	/**
	 * 使用AK&SK初始化账号Client
	 *
	 * @return Client
	 * @throws Exception
	 */
	public static com.aliyun.dysmsapi20170525.Client createClient() throws Exception {
		Config config = new Config()
				// 您的AccessKey ID
				.setAccessKeyId(AdminConfig.getAdminConfig().getAccessKeyId())
				// 您的AccessKey Secret
				.setAccessKeySecret(AdminConfig.getAdminConfig().getAccessKeySecret());
		// 访问的域名
		config.endpoint = "dysmsapi.aliyuncs.com";
		return new com.aliyun.dysmsapi20170525.Client(config);
	}

	/**
	 * 短信下发接口
	 *
	 * @param phone
	 * @param param
	 * @param templateEnum
	 * @return
	 */
	public static boolean sendSms(String phone, JSONObject param, SmsTemplateEnum templateEnum) {
		log.info(String.format("开始下发短信:%s,%s,%s", phone, param, templateEnum));
		boolean result = false;
		RnxSmsSendLog smsSendLog = new RnxSmsSendLog();
		try {
			//设置手机号
			smsSendLog.setPhone(phone);
			//设置参数
			smsSendLog.setEmail(param.toString());
			//设置签名
			smsSendLog.setSignName(templateEnum.getSignName());
			//设置内容
			smsSendLog.setExt(templateEnum.getContent());
			//模板名称 + 模板编号
			smsSendLog.setTemplate(templateEnum.getName() + "#" + templateEnum.getTemplateCode());
			//手机号校验
			if(StringUtils.isBlank(phone) || phone.length() != 11L){
				throw new IllegalArgumentException(
						String.format("短信发送失败->手机号不正确:%s",phone));
			}
			//参数校验
			String[] checks = templateEnum.getChecks();
			if (checks != null && checks.length > 0) {
				//如果缺失参数 则返回异常
				boolean check = Arrays.stream(checks).filter(
						k -> param.containsKey(k) && StringUtils.isNotBlank(param.getString(k))
				).count() == checks.length;
				if (!check) {
					throw new IllegalArgumentException(
							String.format("短信发送失败->参数缺失,需要:%s,提供:%s", Arrays.toString(checks), param));
				}
			}
			//客户端创建
			com.aliyun.dysmsapi20170525.Client client = SmsSender.createClient();
			//参数构建
			SendSmsRequest sendSmsRequest = new SendSmsRequest()
					.setPhoneNumbers(phone)
					.setSignName(templateEnum.getSignName())
					.setTemplateCode(templateEnum.getTemplateCode())
					.setTemplateParam(param.toString());
			String r = SMS_SEND_STATE_OK;
			String error = "";
			//如果是生产环境
			if(AdminConfig.getAdminConfig().isProd()){
				//调用
				SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
				SendSmsResponseBody body = sendSmsResponse.getBody();
				//获取返回code
				r = body.getCode();
				error = body.getMessage();
			}else{
				log.info("非生产环境,限制短信下发,操作成功!");
			}
			if (StringUtils.equals(r, SMS_SEND_STATE_OK)) {
				result = true;
				smsSendLog.setState(1L);
			} else {
				smsSendLog.setState(0L);
				smsSendLog.setErrorDesc(error);
			}
			log.info("短信发送成功!");
		} catch (Exception e) {
			smsSendLog.setState(0L);
			smsSendLog.setErrorDesc(e.getMessage());
			log.error("短信发送失败:->", e);
		} finally {
			smsSendLog.setSendTime(new Date());
			CompletableFuture.runAsync(() -> sendLogService.insertRnxSmsSendLog(smsSendLog));
		}
		return result;
	}

	/**
	 * 短信下发接口
	 *
	 * @param phone
	 * @param param
	 * @param templateCode
	 * @return
	 */
	public static RnxSmsSendLog sendSms(String phone,String name, JSONObject param, String templateCode) {
		log.info(String.format("开始下发短信:%s,%s,%s", phone, param, templateCode));
		RnxSmsSendLog smsSendLog = new RnxSmsSendLog();
		try {
			//设置手机号
			smsSendLog.setPhone(phone);
			if(param != null)
			//设置参数
			smsSendLog.setEmail(param.toString());
			//设置签名
			smsSendLog.setSignName("瑞念信");
			//设置内容
			smsSendLog.setExt(name);
			//模板编号
			smsSendLog.setTemplate(templateCode);
			//手机号校验
			if(StringUtils.isBlank(phone) || phone.length() != 11L){
				throw new IllegalArgumentException(
						String.format("短信发送失败->手机号不正确:%s",phone));
			}
			//客户端创建
			com.aliyun.dysmsapi20170525.Client client = SmsSender.createClient();
			//参数构建
			SendSmsRequest sendSmsRequest = new SendSmsRequest()
					.setPhoneNumbers(phone)
					.setSignName("瑞念信")
					.setTemplateCode(templateCode);
			if(param != null)
				//设置参数
				sendSmsRequest.setTemplateParam(param.toString());
			String r = SMS_SEND_STATE_OK;
			String error = "";
			//如果是生产环境
			if(AdminConfig.getAdminConfig().isProd()){
				//调用
				SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
				SendSmsResponseBody body = sendSmsResponse.getBody();
				//获取返回code
				r = body.getCode();
				error = body.getMessage();
			}else{
				log.info("非生产环境,限制短信下发,操作成功!");
			}
			if (StringUtils.equals(r, SMS_SEND_STATE_OK)) {
				smsSendLog.setState(1L);
			} else {
				smsSendLog.setState(0L);
				smsSendLog.setErrorDesc(error);
			}
			log.info("短信发送成功!");
		} catch (Exception e) {
			smsSendLog.setState(0L);
			smsSendLog.setErrorDesc(e.getMessage());
			log.error("短信发送失败:->", e);
		}
		smsSendLog.setSendTime(new Date());
		sendLogService.insertRnxSmsSendLog(smsSendLog);
		return smsSendLog;
	}
}
